package com.ych.SDK.alibaba.ossSDK;

import com.aliyun.oss.HttpMethod;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.ych.SDK.alibaba.ossSDK.entity.AliOssPublicEntity;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * Author: Usopp.tsui
 * Date: 2021/1/20
 * Time: 11:46
 * Description:阿里云OSS工具类
 */
@Component
public class AliOssUtil {

    /**
     * 文件直传
     *
     * @param objectKey   上传路径
     * @param inputStream 上传流
     * @throws RuntimeException
     */
    public void fileUpload(String objectKey, InputStream inputStream) throws RuntimeException {
        Map map = getCommon(objectKey);
        OSS ossClient = null;
        try {
            ossClient = (OSS) map.get(0);
            AliOssPublicEntity model = (AliOssPublicEntity) map.get(1);
            if (ossClient.doesObjectExist(model.getBucketName(), model.getObjectKey())) {
                throw new RuntimeException("此文件重名,请更改文件名重试!");
            }
            PutObjectRequest putObjectRequest = new PutObjectRequest(model.getBucketName(), model.getObjectKey(), inputStream);
            PutObjectResult putObjectResult = ossClient.putObject(putObjectRequest);
            String eTag = putObjectResult.getETag();
            if (StringUtils.isBlank(eTag)) {
                throw new RuntimeException("文件直传失败");
            }
        } catch (Exception e) {
            throw new RuntimeException("文件直传失败:" + e.getMessage());
        } finally {
            ossClient.shutdown();
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * OSS获取下载签名URL
     *
     * @param objectKey 文件对象key
     * @return 签名URL
     */
    public String getOssObjectDownAuthUrl(String objectKey) throws RuntimeException {
        Map map = getCommon(objectKey);
        OSS ossClient = null;
        try {
            ossClient = (OSS) map.get(0);
            AliOssPublicEntity model = (AliOssPublicEntity) map.get(1);
            GeneratePresignedUrlRequest req =
                    new GeneratePresignedUrlRequest(model.getBucketName(), model.getObjectKey(), HttpMethod.GET);
            //这里设置签名在半个小时后过期
            Date expireDate = new Date(System.currentTimeMillis() + 30L * 60L * 1000L);
            req.setExpiration(expireDate);
            URL url = ossClient.generatePresignedUrl(req);
            String urlStr = url.toString();
            return urlStr;
        } catch (Exception e) {
            throw new RuntimeException("获取下载签名URL失败");
        } finally {
            ossClient.shutdown();
        }
    }

    /**
     * OSS获取下载签名URL
     *
     * @param objectKey  文件对象key
     * @param expireTime 当前时间加多少毫秒后过期，过期时间（毫秒）
     * @return 签名URL
     */
    public String getOssObjectDownAuthUrl(String objectKey, long expireTime) throws RuntimeException {
        Map map = getCommon(objectKey);
        OSS ossClient = null;
        try {
            ossClient = (OSS) map.get(0);
            AliOssPublicEntity model = (AliOssPublicEntity) map.get(1);
            GeneratePresignedUrlRequest req =
                    new GeneratePresignedUrlRequest(model.getBucketName(), model.getObjectKey(), HttpMethod.GET);
            //这里设置签名在半个小时后过期
            Date expireDate = new Date(System.currentTimeMillis() + expireTime);
            req.setExpiration(expireDate);
            URL url = ossClient.generatePresignedUrl(req);
            String urlStr = url.toString();
            return urlStr;
        } catch (Exception e) {
            throw new RuntimeException("获取下载签名URL失败");
        } finally {
            ossClient.shutdown();
        }
    }

    /**
     * COS获取上传签名URL
     *
     * @param objectKey 文件对象key
     * @return 签名URL
     */
    public String getOssObjectUploadAuthUrl(String objectKey) throws RuntimeException {
        Map map = getCommon(objectKey);
        OSS ossClient = null;
        try {
            ossClient = (OSS) map.get(0);
            AliOssPublicEntity model = (AliOssPublicEntity) map.get(1);
            if (ossClient.doesObjectExist(model.getBucketName(), model.getObjectKey())) {
                throw new RuntimeException("此文件重名,请更改文件名重试!");
            }
            Date expirationTime = new Date(System.currentTimeMillis() + 30L * 60L * 1000L);
            GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(model.getBucketName(), model.getObjectKey(), HttpMethod.PUT);
            request.setExpiration(expirationTime);
            request.setContentType("application/octet-stream");//必须要!!!!!!，而且前端上传时，也需要在header里面设置，content-type为"application/octet-stream"
            URL url = ossClient.generatePresignedUrl(request);
            String urlstr = url.toString();
            return urlstr;
        } catch (Exception e) {
            throw new RuntimeException("获取上传签名URL失败" + e.getMessage());
        } finally {
            ossClient.shutdown();
        }
    }

    /**
     * 删除存储对象
     *
     * @param objectKey 文件对象key
     * @return 签名URL
     */
    public void deleteObject(String objectKey) throws RuntimeException {
        Map map = getCommon(objectKey);
        OSS ossClient = null;
        try {
            ossClient = (OSS) map.get(0);
            AliOssPublicEntity model = (AliOssPublicEntity) map.get(1);
            // 指定对象所在的存储桶
            ossClient.deleteObject(model.getBucketName(), model.getObjectKey());
        } catch (RuntimeException clientException) {
            throw new RuntimeException("删除存储对象失败");
        } finally {
            ossClient.shutdown();
        }
    }

    /**
     * 绝对路径更换为相对路径
     *
     * @param url 绝对路径
     * @return 相对路径
     */
    public String getRelativePath(String url) {
        url = url.substring(url.indexOf(".com") + 5, url.indexOf("?"));
        return url;
    }

    /**
     * client公共参数
     *
     * @param objectKey
     * @return
     */
    private Map getCommon(String objectKey) {
        AliOssPublicEntity entity = AliOssPublicEntity.build(objectKey);
        OSS ossClient = new OSSClientBuilder().build(entity.getEndpoint(), entity.getAccessKeyId(), entity.getAccessKeySecret());
//        ClientBuilderConfiguration conf = new ClientBuilderConfiguration();
//        // 私有云要关闭CNAME
//        conf.setSupportCname(false);
//        OSS ossClient = new OSSClientBuilder().build(entity.getEndpoint(),
//                entity.getAccessKeyId(),
//                entity.getAccessKeySecret(),conf);
        Map map = new HashMap();
        map.put(0, ossClient);
        map.put(1, entity);
        return map;
    }
}
